package com.scyshkj.university.wechat.wanxiao;

import com.scyshkj.university.wechat.pay.WechatUnifiedOrderRequestParameter;
import com.scyshkj.university.wechat.utils.MD5Utils;
import com.scyshkj.university.wechat.utils.ParameterToMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.math.BigDecimal;

/**
 * Created by 唐旭 on 2016/11/22.
 */
@Service
public class WanxiaoPayServiceImpl implements WanxiaoPayService {
    @Autowired
    private WanxiaoProperties wanxiaoProperties;
    @Autowired
    private RestTemplate template;
    @Autowired
    private WanxiaoAccessTokenRepository tokenRepository;

    /**
     * 预下单
     *
     * @param amount 下单金额
     * @return 下单结果
     */
    @Override
    public PayApplyResult payApply(BigDecimal amount) {
        WanxiaoAccessToken attribute = tokenRepository.getToken();
        if (attribute == null) {
            return new PayApplyResult();
        }
        PayApplyRequestParameter parameter = new PayApplyRequestParameter(wanxiaoProperties, amount);
        parameter.setAccessToken(attribute.getAccessToken());

        HttpEntity<String> httpEntity = createHttpEntity(parameter);
        ResponseEntity<PayApplyResult> responseEntity = template.postForEntity(wanxiaoProperties.getPayApply() + attribute.getAccessToken()
                , httpEntity, PayApplyResult.class);
        return responseEntity.getBody();
    }

    /**
     * 发起充值
     *
     * @param byOutTradeNo 微信统一下单请求参数
     * @param one          玩校预下单参数结果
     * @return 玩校充值结果
     */
    @Override
    public WanxiaoRechargeResult recharge(WechatUnifiedOrderRequestParameter byOutTradeNo, PayApplyResult one) {
        WanxiaoAccessToken token = tokenRepository.getToken();
        WanxiaoRechargeRequest request = new WanxiaoRechargeRequest(byOutTradeNo, one, wanxiaoProperties);
        HttpEntity<String> httpEntity = createHttpEntity(request);
        ResponseEntity<WanxiaoRechargeResult> responseEntity = template.postForEntity(wanxiaoProperties.getPayRecharge() + token.getAccessToken()
                , httpEntity, WanxiaoRechargeResult.class);
        return responseEntity.getBody();
    }

    /**
     * 生成 httpEntity并添加sign字段
     *
     * @param request 请求参数
     * @return httpEntity
     */
    private HttpEntity<String> createHttpEntity(ParameterToMap request) {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        headers.add("sign", buildSign(request));
        return new HttpEntity<>(request.toUrlString(), headers);
    }

    /**
     * 生成sign字段
     *
     * @param parameter 请求参数对象
     * @return sign字段
     */
    private String buildSign(ParameterToMap parameter) {
        String stringA = parameter.toUrlString();
        stringA = String.format("%s&client_secret=%s", stringA, wanxiaoProperties.getSec());
        return MD5Utils.encode(stringA).toUpperCase();
    }
}
